package cn.com.demo.tool;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Properties;

/**
 * 读取Properties为JAVA POJO工具类
 * @author dongz
 * @date 2023/12/26 20:28
 */
public class PropertiesUtil {
    /**
     * 将properties转换为POJO
     *
     * @param fileName    Properties文件路径
     * @param targetClass 目标DTO类型
     * @param <T>
     * @return 目标DTO的实体对象
     */
    public static <T> T load(String fileName, Class<T> targetClass) {
        return load(PropertiesUtil.class.getResourceAsStream(fileName), targetClass);
    }

    /**
     * 将properties转换为POJO
     *
     * @param fileName    Properties文件路径
     * @param targetClass 目标DTO类型
     * @param <T>
     * @return 目标DTO的实体对象
     */
    public static <T> T load(InputStream in, Class<T> targetClass) {
        if (in == null) {
            return null;
        }
        // 获取目标实例对象
        T data = null;
        try {
            data = targetClass.newInstance();
        } catch (InstantiationException e) {
            System.out.println("实例化失败！");
            return null;
        } catch (IllegalAccessException e) {
            System.out.println("对象实例无法访问！");
            return null;
        }
        // 从流中读取Properties对象
        Properties properties = new Properties();
        try {
            properties.load(in);
        } catch (IOException e) {
            System.out.println("文件读取失败！");
            return null;
        }
        // 遍历 properties 中的属性，动态地将属性值赋给 DTO 对象的属性
        for (String propertyName : properties.stringPropertyNames()) {
            String propertyValue = properties.getProperty(propertyName);
            if (propertyValue == null || propertyValue.length() == 0) {
                continue;
            }
            Field field = null;
            try {
                field = targetClass.getDeclaredField(propertyName);
            } catch (NoSuchFieldException e) {
                try {
                    field = targetClass.getDeclaredField(transPoint(propertyName));
                } catch (NoSuchFieldException ee) {
                }
            }
            if (field == null) {
                System.out.println("属性" + propertyName + "不存在");
                continue;
            }
            field.setAccessible(true);
            // 按类型依次转换目标类型值，并设置到属性中去
            try {
                if (field.getType() == String.class) {
                    field.set(data, propertyValue);
                } else if (field.getType() == boolean.class || field.getType() == Boolean.class) {
                    field.set(data, Boolean.valueOf(propertyValue));
                } else if (field.getType() == int.class || field.getType() == Integer.class) {
                    field.set(data, Integer.parseInt(propertyValue));
                } else if (field.getType() == byte.class || field.getType() == Byte.class) {
                    field.set(data, Byte.valueOf(propertyValue));
                } else {
                    System.out.println(String.format("不支持的数据类型%s,值：%s", field.getType(), propertyValue));
                }
            } catch (IllegalAccessException e) {
                System.out.println("属性设置失败！" + field.getType() + ":" + propertyValue);
            }
        }
        return data;
    }

    /**
     * 将properties中"."分割的key值转换为驼峰命名规则的属性
     * @param inString 输入字符串
     * @return 转换后的字符串
     */
    private static String transPoint(String inString) {
        StringBuilder result = new StringBuilder();
        String[] split = inString.split("\\.");
        for (int i = 0; i < split.length; i++) {
            if (i == 0) {
                result.append(split[i]);
            } else {
                result.append(Character.toUpperCase(split[i].charAt(0))).append(split[i].substring(1));
            }
        }
        return result.toString();
    }
}
